#include "stdafx.h"
#include "ExplorerViewInfo.h"
#include "IShellBrowserImpl.h"

#include <gtl/string/trans.h>

#include <LM.h>
#pragma comment(lib, "Netapi32.lib")

CExplorerViewInfo::CExplorerViewInfo(void)
{
	AddExplorerView();
	m_nCurrViewIndex = 0;
	m_wViewCount = 0;
}

CExplorerViewInfo::~CExplorerViewInfo(void)
{
	Destroy();
}

void CExplorerViewInfo::Destroy()
{
	for(size_t index = m_vecExplorerViewInfo.size(); index >= 1; --index)
	{
		DeleteExplorerView((int)index - 1);
	}

	m_vecExplorerViewInfo.clear();
}

void CExplorerViewInfo::AddExplorerView()
{
	ExplorerViewInfo info = {0};
	info.wID = m_wViewCount++;
	m_vecExplorerViewInfo.push_back(info);
}

void CExplorerViewInfo::DeleteExplorerView(int nIndex)
{
	if(nIndex < 0 || nIndex >= (int)m_vecExplorerViewInfo.size())
		return;

	ExplorerViewInfo& info = m_vecExplorerViewInfo[nIndex];
	if(info.pCurrShellFolder != NULL)
		info.pCurrShellFolder->Release();

	if(info.pShellView != NULL)
	{
		info.pShellView->UIActivate(SVUIA_DEACTIVATE);
		info.pShellView->DestroyViewWindow();
		info.pShellView->Release();
	}

	m_vecExplorerViewInfo.erase(m_vecExplorerViewInfo.begin() + nIndex);
}

bool CExplorerViewInfo::NetShareOperate(const CString& strPathName, bool bAdd)
{
	if(!::PathIsDirectory(strPathName))
		return false;

	if(bAdd)
	{
		SHARE_INFO_2 shInfo = {0};

#ifdef UNICODE
		shInfo.shi2_netname = (LPWSTR)(LPCTSTR)::PathFindFileName(strPathName);    
		shInfo.shi2_path = (LPWSTR)(LPCTSTR)strPathName;
#else
		std::wstring wstrName = gtl::string::trans(::PathFindFileName(strPathName));
		shInfo.shi2_netname = (LPWSTR)wstrName.data();
		std::wstring wstrPath = gtl::string::trans(strPathName);
		shInfo.shi2_path = (LPWSTR)wstrPath.data();
#endif
		shInfo.shi2_type = STYPE_DISKTREE; // disk drive
		shInfo.shi2_max_uses = 100;

		DWORD dwParmErr = 0;
		NET_API_STATUS status = NetShareAdd(NULL, 2, (LPBYTE)&shInfo, &dwParmErr);
		return status == 0;
	}
	else
	{
#ifdef UNICODE
		CString strName = (LPCTSTR)::PathFindFileName(strPathName);
		NET_API_STATUS status = NetShareDel(NULL, ::PathFindFileName(strPathName), 0);
#else
		std::wstring wstrName = gtl::string::trans(::PathFindFileName(strPathName));
		NET_API_STATUS status = NetShareDel(NULL, (LPWSTR)wstrName.data(), 0);
#endif
		return status == 0;
	}

	return true;
}

bool CExplorerViewInfo::NetShareCheck(const CString& strPathName)
{
	PSHARE_INFO_502 BufPtr = NULL;
	std::wstring wstrName = ::PathFindFileName(strPathName);
	NET_API_STATUS status = ::NetShareGetInfo(NULL, (LPWSTR)wstrName.data(), 502, (LPBYTE*)&BufPtr);
	if(status == ERROR_SUCCESS)
	{
		bool result = BufPtr->shi502_path != NULL;
		NetApiBufferFree(BufPtr);
		return result;
	}

//#ifdef UNICODE
//	CString strName = (LPWSTR)(LPCTSTR)::PathFindFileName(strPathName);
//	NET_API_STATUS status = ::NetShareCheck(NULL, (LPWSTR)strName, 0);
//#else
//	std::wstring wstrName = gtl::string::trans(::PathFindFileName(strPathName));
//	NET_API_STATUS status = ::NetShareCheck(L"\\\\smart", (LPWSTR)wstrName.data(), 0);
//#endif
//	return status == 0;

	return false;
}

void CExplorerViewInfo::AddFolderSetting(LPCTSTR lpszDesc, const VectorFolderSetting& vecPrevFdSetting, BOOL bValue)
{
	using namespace std;
	VectorFolderSetting& vecFdSetting = GetCurrFolderSetting();

	if(lpszDesc == NULL)
	{
		VectorFolderSetting::const_iterator last;
		last = std::find_if(vecPrevFdSetting.begin(), vecPrevFdSetting.end(), std::bind2nd(equal_fs(), _T("<->")));
		for(VectorFolderSetting::const_iterator first = vecPrevFdSetting.begin(); first != last; ++first)
		{
			vecFdSetting.push_back(*first);
		}
		vecFdSetting.push_back(std::make_pair(_T("<->"), FALSE));
	}
	else if(vecPrevFdSetting.empty())
	{
		if(vecFdSetting.end() != find_if(vecFdSetting.begin(), vecFdSetting.end(), bind2nd(equal_fs(), lpszDesc)))
			return;

		vecFdSetting.insert(vecFdSetting.begin(), std::make_pair(lpszDesc, bValue));

		VectorFolderSetting::iterator ite;
		ite = find_if(vecFdSetting.begin(), vecFdSetting.end(), bind2nd(equal_fs(), _T("<->")));
		if(ite != vecFdSetting.end())
			std::sort(vecFdSetting.begin(), ++ite, great_fs_len());
	}
}

BOOL CExplorerViewInfo::GetFolderSetting(const CString& strDesc, const VectorFolderSetting* pVecFdSetting /* = NULL */)
{
	using namespace std;
	const VectorFolderSetting& vecFdSetting = (pVecFdSetting == NULL) ? GetCurrFolderSetting() : *pVecFdSetting;

	VectorFolderSetting::const_iterator ite;
	ite = find_if(vecFdSetting.begin(), vecFdSetting.end(), bind2nd(equal_fs(), strDesc));
	if(ite == vecFdSetting.end())
		return TRUE;

	return ite->second;
}

WORD CExplorerViewInfo::GetViewID()
{
	if(m_vecExplorerViewInfo.empty())
		return 0;

	if(m_nCurrViewIndex <= 0 || m_nCurrViewIndex >= (int)m_vecExplorerViewInfo.size())
		return m_vecExplorerViewInfo[0].wID;

	return m_vecExplorerViewInfo[m_nCurrViewIndex].wID;
}

HWND& CExplorerViewInfo::GetListViewWnd()
{
	ASSERT(!m_vecExplorerViewInfo.empty());

	if(m_nCurrViewIndex <= 0 || m_nCurrViewIndex >= (int)m_vecExplorerViewInfo.size())
		return m_vecExplorerViewInfo[0].hWndListView;

	return m_vecExplorerViewInfo[m_nCurrViewIndex].hWndListView;
}

CString& CExplorerViewInfo::GetPathName()
{
	ASSERT(!m_vecExplorerViewInfo.empty());

	if(m_nCurrViewIndex <= 0 || m_nCurrViewIndex >= (int)m_vecExplorerViewInfo.size())
		return m_vecExplorerViewInfo[0].strPathName;

	return m_vecExplorerViewInfo[m_nCurrViewIndex].strPathName;
}

CString& CExplorerViewInfo::GetPrevPathName()
{
	ASSERT(!m_vecExplorerViewInfo.empty());

	if(m_nCurrViewIndex <= 0 || m_nCurrViewIndex >= (int)m_vecExplorerViewInfo.size())
		return m_vecExplorerViewInfo[0].strPrevPathName;

	return m_vecExplorerViewInfo[m_nCurrViewIndex].strPrevPathName;
}

CString& CExplorerViewInfo::GetTabTitle()
{
	ASSERT(!m_vecExplorerViewInfo.empty());

	if(m_nCurrViewIndex <= 0 || m_nCurrViewIndex >= (int)m_vecExplorerViewInfo.size())
		return m_vecExplorerViewInfo[0].strTabTitle;

	return m_vecExplorerViewInfo[m_nCurrViewIndex].strTabTitle;
}

IShellView*& CExplorerViewInfo::GetShellView()
{
	ASSERT(!m_vecExplorerViewInfo.empty());

	if(m_nCurrViewIndex <= 0 || m_nCurrViewIndex >= (int)m_vecExplorerViewInfo.size())
		return m_vecExplorerViewInfo[0].pShellView;

	return m_vecExplorerViewInfo[m_nCurrViewIndex].pShellView;
}

LPITEMIDLIST& CExplorerViewInfo::GetCurrPidlFQ()
{
	ASSERT(!m_vecExplorerViewInfo.empty());

	if(m_nCurrViewIndex <= 0 || m_nCurrViewIndex >= (int)m_vecExplorerViewInfo.size())
		return m_vecExplorerViewInfo[0].pCurrPidlFQ;

	return m_vecExplorerViewInfo[m_nCurrViewIndex].pCurrPidlFQ;
}

IShellFolder*& CExplorerViewInfo::GetCurrShellFolder()
{
	ASSERT(!m_vecExplorerViewInfo.empty());

	if(m_nCurrViewIndex <= 0 || m_nCurrViewIndex >= (int)m_vecExplorerViewInfo.size())
		return m_vecExplorerViewInfo[0].pCurrShellFolder;

	return m_vecExplorerViewInfo[m_nCurrViewIndex].pCurrShellFolder;
}

CExplorerViewInfo::VectorFolderSetting& CExplorerViewInfo::GetCurrFolderSetting()
{
	ASSERT(!m_vecExplorerViewInfo.empty());

	if(m_nCurrViewIndex <= 0 || m_nCurrViewIndex >= (int)m_vecExplorerViewInfo.size())
		return m_vecExplorerViewInfo[0].vecFolderSetting;

	return m_vecExplorerViewInfo[m_nCurrViewIndex].vecFolderSetting;
}

CExplorerViewInfo::VectorFolderSetting& CExplorerViewInfo::GetPrevFolderSetting()
{
	ASSERT(!m_vecExplorerViewInfo.empty());

	if(m_nCurrViewIndex <= 0 || m_nCurrViewIndex >= (int)m_vecExplorerViewInfo.size())
		return m_vecExplorerViewInfo[0].vecPrevFdSetting;

	return m_vecExplorerViewInfo[m_nCurrViewIndex].vecPrevFdSetting;
}